<?php
/**
 * Copyright (c) 2006-2008, Julien PORTALIER
 * http://featherphp.googlecode.com/
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 */

/**
 * Manages sessions' data.
 */
class SessionComponent
{
	private $started = false;
	
	/**
	 * Prepares the session.
	 * 
	 * @param $Controller Object
	 */
	function startup(Controller $Controller)
	{
		# has a session already been started?
		$sid = session_id();
		if (!empty($sid)) {
			return;
		}
		
		# config
		ini_set('session.name', Core::session_cookie);
		ini_set('session.use_only_cookies', '1');
#		ini_set('session.save_path', TMP.'sessions'.DS);
		
		$expire = is_string(Core::session_expire) ? strtotime(Core::session_expire) : Core::session_expire;
		session_set_cookie_params($expire, Core::session_path, Core::session_domain);
		
		# webservice?
		if (!empty($_REQUEST[Core::session_cookie])) {
			session_id($_REQUEST[Core::session_cookie]);
		}
		
		# autostart?
		if (Core::session_auto
			or isset($_COOKIE[Core::session_cookie])
			or isset($_REQUEST[Core::session_cookie]))
		{
			$this->start();
		}
	}
	
	/**
	 * Starts a session.
	 */
	function start()
	{
		# do not start a session if one has already been started
		if ($this->started) {
			return;
		}
		
		# start
		$this->started = true;
		session_start();
		
		# browsers may cache pages, proxies may not
		header('Pragma: ');
		header('Expires: ');
		header('Cache-Control: s-maxage=1, proxy-revalidate');
#		header("X-LIGHTTPD-SID: ".session_id());
		
		# sec. 1: prevent session fixation (session must exist)
		if (!isset($_SESSION['Config.init']))
		{
			session_regenerate_id(true);
			$_SESSION['Config.init'] = true;
		}
		
		# sec. 2: prevent session hijacking (UA musn't change between requests)
		if (isset($_SERVER['HTTP_USER_AGENT']))
		{
			if (isset($_SESSION['Config.UA']))
			{
				if ($_SESSION['Config.UA'] != md5($_SERVER['HTTP_USER_AGENT']))
				{
					session_regenerate_id(true);
					$_SESSION['Config.init'] = true;
					$_SESSION['Config.UA']   = md5($_SERVER['HTTP_USER_AGENT']);
				}
			}
			else {
				$_SESSION['Config.UA'] = md5($_SERVER['HTTP_USER_AGENT']);
			}
		}
	}
	
	/**
	 * Destroys curent session.
	 */
	function destroy()
	{
		$this->started = false;
		session_destroy();
	}
	
	/**
	 * Passes a text message to the next page.
	 * 
	 * This is useful to message the user after a redirection.
	 * 
	 * @param $mesg String  Text message to pass.
	 * @param $type Integer Could be: notice, error, warning, etc.
	 */
	function set_flash($mesg, $type=null)
	{
		$_SESSION['Flash.mesg'] = $mesg;
		$_SESSION['Flash.type'] = $type;
	}
	
	/**
	 * Displays a passed message.
	 * 
	 * @return String The passed message.
	 * @param $fancy Boolean[optional] An fancy HTML formated message or just plain text?
	 */
	function flash($fancy=true)
	{
		if (isset($_SESSION['Flash.mesg']))
		{
			$mesg = $_SESSION['Flash.mesg'];
			$type = $_SESSION['Flash.type'];
			
			unset($_SESSION['Flash.mesg'], $_SESSION['Flash.code']);
			return $fancy ? '<p class="message'.(empty($type) ? null : " $type").
				'" id="message"><span>'.$mesg.'</span></p>' : $mesg;
		}
	}
}
?>